<template>
  <el-dialog
    v-model="visible"
    :title="title"
    :width="width"
    @close="handleClose"
  >
    <el-form
      ref="formRef"
      :model="modelValue"
      :rules="rules"
      :label-width="labelWidth"
      v-bind="formProps"
    >
      <template v-for="field in fields" :key="field.prop">
        <el-form-item
          v-if="!field.hidden"
          :label="field.label"
          :prop="field.prop"
        >
          <!-- 输入框 -->
          <el-input
            v-if="field.type === 'input'"
            v-model="modelValue[field.prop]"
            :placeholder="field.placeholder"
            :disabled="field.disabled"
            v-bind="field.props"
          />
          
          <!-- 文本域 -->
          <el-input
            v-else-if="field.type === 'textarea'"
            v-model="modelValue[field.prop]"
            type="textarea"
            :placeholder="field.placeholder"
            :disabled="field.disabled"
            v-bind="field.props"
          />
          
          <!-- 数字输入框 -->
          <el-input-number
            v-else-if="field.type === 'number'"
            v-model="modelValue[field.prop]"
            :placeholder="field.placeholder"
            :disabled="field.disabled"
            v-bind="field.props"
          />
          
          <!-- 选择框 -->
          <el-select
            v-else-if="field.type === 'select'"
            v-model="modelValue[field.prop]"
            :placeholder="field.placeholder"
            :disabled="field.disabled"
            :clearable="field.clearable"
            v-bind="field.props"
            style="width: 100%"
          >
            <el-option
              v-for="option in field.options"
              :key="option.value"
              :label="option.label"
              :value="option.value"
            />
          </el-select>
          
          <!-- 开关 -->
          <el-switch
            v-else-if="field.type === 'switch'"
            v-model="modelValue[field.prop]"
            :disabled="field.disabled"
            v-bind="field.props"
          />
          
          <!-- 日期选择器 -->
          <el-date-picker
            v-else-if="field.type === 'date'"
            v-model="modelValue[field.prop]"
            type="date"
            :placeholder="field.placeholder"
            :disabled="field.disabled"
            value-format="YYYY-MM-DD"
            v-bind="field.props"
            style="width: 100%"
          />
          
          <!-- 自定义插槽 -->
          <slot
            v-else-if="field.type === 'slot'"
            :name="field.slot"
            :field="field"
            :model="modelValue"
            :disabled="field.disabled"
          />
        </el-form-item>
      </template>
    </el-form>
    
    <template #footer>
      <slot name="footer" :form="formRef" :loading="loading">
        <el-button @click="handleClose">取消</el-button>
        <el-button 
          type="primary" 
          :loading="loading" 
          @click="handleSubmit"
        >
          {{ confirmText }}
        </el-button>
      </slot>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
import { ref, computed, reactive } from 'vue'
import { ElMessage, type FormInstance, type FormRules } from 'element-plus'

// 字段配置类型
interface FieldConfig {
  prop: string
  label: string
  type: 'input' | 'textarea' | 'number' | 'select' | 'switch' | 'date' | 'slot'
  placeholder?: string
  disabled?: boolean
  hidden?: boolean
  clearable?: boolean
  props?: Record<string, any>
  options?: Array<{ label: string; value: string | number }>
  slot?: string
  rules?: any
}

interface Props {
  visible: boolean
  title?: string
  width?: string
  modelValue: Record<string, any>
  fields: FieldConfig[]
  rules?: FormRules
  loading?: boolean
  confirmText?: string
  labelWidth?: string
  formProps?: Record<string, any>
}

const props = withDefaults(defineProps<Props>(), {
  title: '表单',
  width: '500px',
  loading: false,
  confirmText: '确定',
  labelWidth: '80px',
  formProps: () => ({}),
  rules: () => ({})
})

interface Emits {
  (e: 'update:visible', value: boolean): void
  (e: 'update:modelValue', value: Record<string, any>): void
  (e: 'submit'): void
  (e: 'close'): void
}

const emit = defineEmits<Emits>()

const formRef = ref<FormInstance>()

const visible = computed({
  get: () => props.visible,
  set: (value) => emit('update:visible', value)
})

const modelValue = computed({
  get: () => props.modelValue,
  set: (value) => emit('update:modelValue', value)
})

// 合并字段规则和传入规则
const mergedRules = computed(() => {
  const fieldRules: FormRules = {}
  props.fields.forEach(field => {
    if (field.rules) {
      fieldRules[field.prop] = field.rules
    }
  })
  return { ...fieldRules, ...props.rules }
})

const handleSubmit = async () => {
  if (!formRef.value) return
  
  try {
    await formRef.value.validate()
    emit('submit')
  } catch (error) {
    ElMessage.error('请检查表单信息')
  }
}

const handleClose = () => {
  emit('close')
  visible.value = false
}
</script>